package bancosys.tec.persist.base;

import jmine.tec.persist.PersistMessages;

import org.springframework.transaction.TransactionStatus;

import bancosys.tec.exception.BusinessException;
import bancosys.tec.persist.PersistAuthBOBaseTestCase;
import bancosys.tec.persist.PersistBusBaseTestCase;
import bancosys.tec.persist.authorization.annotation.DisplayName;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.persist.entities.domain.Filho;
import bancosys.tec.persist.entities.domain.Pai;
import bancosys.tec.persist.exception.PersistenceException;

/**
 * Testa se quando é gerado um stale state excepion, a mensagem de erro é a esperada
 * 
 * @author heitor.marcos
 */

public class AuthPersistableStaleStateTestCase extends PersistBusBaseTestCase {
    public void testStaleStateErrorMessage() throws PersistenceException, BeanNotFoundException, InterruptedException {
        TransactionStatus status = this.getHelper().getTransactionStatus();
        Pai element1 = new MockPaiTestCase().getSavedTestData().get(0);
        Pai element2 = new MockPaiTestCase().getSavedTestData().get(0);
        try {
            element1.setName("d");
            element2.setName("e");
            element1.getPersister().save();
            element1.getAuthorizer().authorize();
            element2.getPersister().save();
            element2.getAuthorizer().authorize();
        } catch (BusinessException e) {
            // garante que é a mensagem de stale state esperada.
            String msg =
                    PersistMessages.STALE_STATE_IN_AUTHORIZATION.create(Pai.class.getAnnotation(DisplayName.class).value(), element1.getPk())
                            .getMessage();
            assertEquals(msg, e.getMessage());
            return;
        } finally {
            this.getHelper().rollback(status);
        }
        fail("Deveria ter gerado a exception de stale state");
    }

    public void testStaleStateErrorMessageNoDisplayName() throws PersistenceException, BeanNotFoundException, InterruptedException {
        TransactionStatus status = this.getHelper().getTransactionStatus();
        Filho element1 = new MockFilhoTestCase().getSavedTestData().get(0);
        Filho element2 = new MockFilhoTestCase().getSavedTestData().get(0);
        try {
            element1.setName("d");
            element2.setName("e");
            element1.getPersister().save();
            element1.getAuthorizer().authorize();
            element2.getPersister().save();
            element2.getAuthorizer().authorize();
        } catch (BusinessException e) {
            // garante que é a mensagem de stale state esperada.
            String msg = PersistMessages.STALE_STATE_IN_AUTHORIZATION.create(Filho.class.getName(), element1.getPk()).getMessage();
            assertEquals(msg, e.getMessage());
            return;
        } finally {
            this.getHelper().rollback(status);
        }
        fail("Deveria ter gerado a exception de stale state");
    }

    @Override
    protected void initializeTestData() {

    }

    @Override
    public String getControllerSpringId() {
        return "persistTestController";
    }

    class MockFilhoTestCase extends PersistAuthBOBaseTestCase<Filho> {

        String[] name = new String[]{ "a", "b" };

        @Override
        protected void fillData(int idx, Filho bo) {
            bo.setName(this.name[idx]);
        }

        @Override
        protected void compareData(int idx, Filho bo) throws BeanNotFoundException {
            // empty
        }
    }

    class MockPaiTestCase extends PersistAuthBOBaseTestCase<Pai> {

        String[] name = new String[]{ "a", "b" };

        @Override
        protected void fillData(int idx, Pai bo) {
            bo.setName(this.name[idx]);
        }

        @Override
        protected void compareData(int idx, Pai bo) throws BeanNotFoundException {
            // empty
        }
    }
}
